package com.basker.pisces.core.query.criteria;

import org.springframework.util.StringUtils;

import com.basker.pisces.core.operator.CompareOperator;
import com.basker.pisces.core.operator.CompareOperatorManager;
import com.basker.pisces.core.operator.ICompareOperatorHandler;
import com.basker.pisces.core.operator.handler.SqlCompareOperatorHandler;

/**
 * 单个条件
 *
 * @author hangwen
 */
public class Criterion {
    public static final Object NO_CRITERION_VALUE = new Object();

    public static final String AND = "AND";
    public static final String OR = "OR";

    private String fieldId;
    private String fieldName;
    private String operatorId;
    private Object value;
    private String andOr = AND;
    private boolean beginBracket = false;
    private boolean endBracket = false;
    private boolean parameterExpression = true;

    private String existRootTableName;
    private boolean exist;

    public String getAndOr() {
        return andOr;
    }

    /**
     * 获取Sql条件表达式
     *
     * @return
     */
    public String getCondition() {
        return this.getCondition("");
    }

    /**
     * 获取Sql条件表达式
     *
     * @param hostTableAlias 字段的所属表别名
     * @return
     */
    public String getCondition(String hostTableAlias) {
        String condition = this.genCondition();

        if (!StringUtils.isEmpty(condition)) {
            if (StringUtils.isEmpty(hostTableAlias)) {
                hostTableAlias = "";
            } else {
                hostTableAlias += ".";
            }

            return condition.replaceAll("\\" + SqlCompareOperatorHandler.HOST_VAR + ".", hostTableAlias);
        }

        return null;
    }

    public String getExistRootTableName() {
        return existRootTableName;
    }

    public String getFieldId() {
        return fieldId;
    }

    public String getFieldName() {
        return fieldName;
    }

    public String getOperatorId() {
        return operatorId;
    }

    public Object getUpdateValue() {
        CompareOperator operator = this.getCompareOperator();
        ICompareOperatorHandler handler = operator.getOperatorHandler();

        Object updateValue = this.value;
        if (updateValue != null) {
            updateValue = handler.updateValue(updateValue);
        }

        return updateValue;
    }

    public Object getValue() {
        return value;
    }

    public boolean isBeginBracket() {
        return beginBracket;
    }

    public boolean isEndBracket() {
        return endBracket;
    }

    public boolean isExist() {
        return exist;
    }

    public boolean isParameterExpression() {
        return parameterExpression;
    }

    public void setAndOr(String andOr) {
        this.andOr = andOr;
    }

    public void setBeginBracket(boolean beginBracket) {
        this.beginBracket = beginBracket;
    }

    public void setEndBracket(boolean endBracket) {
        this.endBracket = endBracket;
    }

    public void setExist(boolean exist) {
        this.exist = exist;
    }

    public void setExistRootTableName(String existRootTableName) {
        this.existRootTableName = existRootTableName;
    }

    public void setFieldId(String fieldId) {
        this.fieldId = fieldId;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public void setOperatorId(String operatorId) {
        this.operatorId = operatorId;
    }

    public void setParameterExpression(boolean parameterExpression) {
        this.parameterExpression = parameterExpression;
    }

    public void setValue(Object value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return this.getCondition();
    }

    private String genCondition() {
        CompareOperator operator = this.getCompareOperator();
        ICompareOperatorHandler handler = operator.getOperatorHandler();

        Object updateValue = this.value;
        if (updateValue != null) {
            updateValue = handler.updateValue(updateValue);
        }

        String fieldName = this.getFieldName();
        boolean isParameterExpression = this.isParameterExpression();

        return handler.getConditionExpression(fieldName, operator, updateValue, isParameterExpression);
    }

    private CompareOperator getCompareOperator() {
        return CompareOperatorManager.getOperator(this.getOperatorId());
    }

}
